package com.unittec.zk.provider.common;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import com.unittec.zk.provider.scope.ThreadLocalScope;
import com.unittec.zk.provider.utils.StringUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.ParameterizedTypeReference;

import com.unittec.zk.provider.ApplicationContextProvider;
import com.unittec.zk.provider.service.HystrixRestTemplateService;
import com.unittec.zk.sdk.auth.request.Req10000;
import com.unittec.zk.sdk.auth.request.Req101004;
import com.unittec.zk.sdk.auth.response.Res10000;
import com.unittec.zk.sdk.root.common.FieldConstants;
import com.unittec.zk.sdk.root.domain.GatewayRequest;
import com.unittec.zk.sdk.root.domain.Result;

/**
 * @author wuxinwei
 */
public class ServiceFuncUtils {
    /**
     *
     */
    private static final Map<String, Res10000> SERVICE_MAP = new ConcurrentHashMap<>();

    /**
     * 获取应用的所有动态路由服务地址
     */
    private static final String SERVICE_ROUTEURL_ALL = "http://zk-auth-101/10000";
    /**
     * 获取单个
     */
    private static final String SERVICE_ROUTEURL_METHOD = "http://zk-auth-101/10004";

    /**
     *
     */
    private volatile static HystrixRestTemplateService HYSTRIXRESTTEMPLATE_SERVICE = null;

    public static boolean isSysFun(String method) {
        initHystrixRestTemplateService();
        Res10000 service = ServiceFuncUtils.fetchService(method);
        if (null != service) {
            return service.isSysFun();
        }

        return false;
    }

    /**
     *
     * @param method
     */
    public static void deleteService(String method) {
        if (StringUtil.isEmpty(method)) {
            return;
        }
        SERVICE_MAP.remove(method);
    }

    /**
     * 查询所有路由信息
     *
     * @param method
     * @return
     */
    public static Res10000 fetchService(String method) {
        Res10000 service = SERVICE_MAP.get(method);
        // 如果本地获取的信息为空，请求鉴权服务获取最新的服务信息
        // 解决新版本加入新服务，不用停网关就能实时刷新拿到最新的服务路由信息
        if (null == service) {
            if (SERVICE_MAP.size() == 0) {
                synchronized (ServiceFuncUtils.class) {
                    if (SERVICE_MAP.size() == 0) {
                        init();
                    }
                }
                service = SERVICE_MAP.get(method);
            }
        }
        if (null == service) {
            service = findByMethod(method);
            if (service != null && StringUtils.isNotBlank(service.getFunctionCode())) {
                SERVICE_MAP.put(service.getFunctionCode(), service);
                return service;
            }
        }
        return service;
    }

    /**
     * 初始化
     */
    public static void init() {
        initHystrixRestTemplateService();
        List<Res10000> list = findAll();
        addList(list);
    }

    /**
     *
     * @param list
     */
    private static void addList(List<Res10000> list) {
        if (null != list) {
            for (Res10000 sr : list) {
                if (null == sr.getFunctionCode()) {
                    continue;
                }
                SERVICE_MAP.put(sr.getFunctionCode(), sr);
            }
        }
    }

    /**
     * @return
     */
    private static List<Res10000> findAll() {
        GatewayRequest<Req10000> request = new GatewayRequest<>();
        Req10000 content = new Req10000();
        request.setContent(content);
        request.setMethod("10000");
        ThreadLocalScope.AuthData authData = ThreadLocalScope.getAuthData();
        initHystrixRestTemplateService();
        Result<List<Res10000>> result =
            HYSTRIXRESTTEMPLATE_SERVICE.exchange(Md5.getMd5(FieldConstants.SYS_REQUEST_SOURCE_ID), SERVICE_ROUTEURL_ALL,
                request, authData, new ParameterizedTypeReference<Result<List<Res10000>>>() {});
        if (result.isSuccess()) {
            return result.getData();
        }
        return null;
    }

    private static void initHystrixRestTemplateService() {
        if (HYSTRIXRESTTEMPLATE_SERVICE == null) {
            synchronized (ServiceFuncUtils.class) {
                if (null == HYSTRIXRESTTEMPLATE_SERVICE) {
                    HYSTRIXRESTTEMPLATE_SERVICE = ApplicationContextProvider.getBean(HystrixRestTemplateService.class);
                }
            }
        }
    }

    /**
     * 获取单个
     *
     * @return
     */
    private static Res10000 findByMethod(String method) {
        GatewayRequest<Req101004> request = new GatewayRequest<>();
        Req101004 req101004 = new Req101004();
        req101004.setFunctionCode(method);
        request.setContent(req101004);
        request.setMethod("10004");
        ThreadLocalScope.AuthData authData = ThreadLocalScope.getAuthData();
        initHystrixRestTemplateService();
        Result<Res10000> result = HYSTRIXRESTTEMPLATE_SERVICE.exchange(Md5.getMd5(FieldConstants.SYS_REQUEST_SOURCE_ID),
            SERVICE_ROUTEURL_METHOD, request, authData, new ParameterizedTypeReference<Result<Res10000>>() {});
        if (result.isSuccess()) {
            return result.getData();
        }
        return null;
    }
}
